#pragma once
//This is the cpp file containing all the actual code for the map class. I separated it out because I'm going to be needing a lot more
//Than just one line for some of this stuff. Such as the glDraw. -Matt

#include "Map.h"
#include "v2d.h"

Map::Map()
{
	//Constructor.
	//The original map was a dynamically allocated array of 13 x 7, but I realized it just needed to be static. Therefore, it be static. -Matt
	level = 1;
}

Map::~Map()
{
	
}
//When I got this far I tested it to make sure it compiles. It does, and with no heap overflow thing at the end. =D -Matt

void Map::nextPosition(int rows, int cols)
{
	if(rows == 6 && cols == 3) //Basically, is it in the center piece?
	{
		for(int i = 1; i < 4; i++)
		{
			//Because it's the center, I don't need to worry about it going out of bounds using this!
			int x = i * 2;
			map[rows - x][cols].next(); //Left
			map[rows + x][cols].next(); //Right
			map[rows + i][cols + i].next(); //Upper Right.
			map[rows - i][cols - i].next(); //Lower left
			map[rows + i][cols - i].next(); //Lower right.
			map[rows - i][cols + i].next(); //Upper left.
		}
	}

	else
	{
		int x = rows + map[rows][cols].getDots();
		int y = cols + map[rows][cols].getDots();
		int a = rows - map[rows][cols].getDots();
		int b = cols - map[rows][cols].getDots();
		int x2 = rows + map[rows][cols].getDots() * 2;
		int a2 = rows - map[rows][cols].getDots() * 2;

		//Now for the new parts:
		if(!(x > 12 || y > 6) && !(map[x][y].getTaken()))
			map[x][y].next(); //Upper right.
		if(!(x2 > 12) && !(map[x2][cols].getTaken()))
			map[x2][cols].next(); //Right.
		if(!(a < 0 || b < 0) && !(map[a][b].getTaken()))
			map[a][b].next(); //Lower Left.
		if(!(x > 12 || b < 0) && !(map[x][b].getTaken()))
			map[x][b].next(); //Lower right.
		if(!(a < 0 || y > 6) && !(map[a][y].getTaken()))
			map[a][y].next(); //Upper left.
		if(!(a2 < 0) && !(map[a2][cols].getTaken()))
			map[a2][cols].next();
	}
}


void Map::deSelect()
{
	for(int i = 0; i < 13; i++)
	{
		for(int k = 0; k < 7; k++)
		{
			if(map[i][k].posNext())
			{
				map[i][k].next(); //This should deselect it. 
			}
		}
	}
}

void Map::setSurvive()
{
	for(int i = 0; i < 13; i++)
	{
		for(int k = 0; k < 7; k++)
		{
			switch(map[i][k].getDots())
			{
			case 0:
				if((i == 6) && (k == 3))
				{
					map[i][k].setSurvive(false);	
				}
				else
				{
					map[i][k].setSurvive(true);
					map[i][k].changeLevel(level+1);
				}
				break;
			case 1:
			case 2:
			case 3:
			case 4:
				{
					map[i][k].setSurvive(false);
					break;
				}
			}
		}
	}
}

void Map::initCells()
{
	float ex = 0, why = 0;
	for(int rows = 0; rows < 7; rows++)
	{
		for(int cols = 0; cols < 13; cols++)
		{
			//Yet another failed attempt, but I think this next time I got it. I can use two floats to calculate where the cells should be.
			ex = -0.9 + (cols * 0.15);
			why = 0.9 - (rows * 0.3);
			map[cols][rows].setPos(ex, why);
			map[cols][rows].setIndex(cols,rows);
		}
	}
	//Because I don't think there is a single predictable algorithm for the dots, I have to input them all manually.
	//firs row
	map[3][0].setDots(1);
	map[5][0].setDots(2);								//4 circls
	map[7][0].setDots(2);
	map[9][0].setDots(3);
	//second row
	map[2][1].setDots(2);
	map[4][1].setDots(0);
	map[6][1].setDots(1);								//5circls
	map[8][1].setDots(0);
	map[10][1].setDots(2);

	//third row
	map[1][2].setDots(4); 
	map[3][2].setDots(0); 
	map[5][2].setDots(0); 
	map[7][2].setDots(3);								//6 circls
	map[9][2].setDots(1); 
	map[11][2].setDots(2);  

	//fourth row
	map[0][3].setDots(1);
	map[2][3].setDots(2);
	map[4][3].setDots(0);
	map[6][3].setDots(0);								//7 circls
	map[8][3].setDots(0);
	map[10][3].setDots(0);
	map[12][3].setDots(1);

	//fifth row
	map[1][4].setDots(2); 
	map[3][4].setDots(1); 
	map[5][4].setDots(2); 
	map[7][4].setDots(0);								//6 circls
	map[9][4].setDots(1); 
	map[11][4].setDots(4); 
	//six row
	map[2][5].setDots(3);
	map[4][5].setDots(0);
	map[6][5].setDots(2);								//5 circls
	map[8][5].setDots(0);
	map[10][5].setDots(4);

	// seven row
	map[3][6].setDots(2);
	map[5][6].setDots(2);
	map[7][6].setDots(1);								//4 circls
	map[9][6].setDots(1);

	/*Leseamus
	Hey matt sorry for doing this for you. I was bord and I got tired of reading my code so I decided to do your's. 
	Sorry about that. I think there might be a patter on the way I set up the dots on the map. I seperated them by rows and the one's
	that has a zero for dots are the save area/Middle area. I made it look just like the bord game for the firs level. If you have any
	question just email me or leave a comment.
	*/
	setSurvive();
}

void Map::drawLines()
{
	V2DF v1, v2;
	v1.set(map[0][3].getX(), map[0][3].getY());
	v2.set(map[3][6].getX(), map[3][6].getY());
	v1.glDrawTo(v2);
	//Second Line.
	v2.set(map[12][3].getX(), map[12][3].getY());
	v1.glDrawTo(v2);
	//Third Line.
	v2.set(map[3][0].getX(), map[3][0].getY());
	v1.glDrawTo(v2);
	//There are twenty two lines, approximately.
	v1.set(map[1][4].getX(), map[1][4].getY());
	v2.set(map[5][0].getX(), map[5][0].getY());
	v1.glDrawTo(v2);
	//Fifth.
	v2.set(map[11][4].getX(), map[11][4].getY());
	v1.glDrawTo(v2);
	//Sixth
	v1.set(map[2][5].getX(), map[2][5].getY());
	v2.set(map[7][0].getX(), map[7][0].getY());
	v1.glDrawTo(v2);
	//Seventh
	v2.set(map[10][5].getX(), map[10][5].getY());
	v1.glDrawTo(v2);
	//Eigth
	v1.set(map[3][6].getX(), map[3][6].getY());
	v2.set(map[9][0].getX(), map[9][0].getY());
	v1.glDrawTo(v2);
	//Nine
	v2.set(map[9][6].getX(), map[9][6].getY());
	v1.glDrawTo(v2);
	//Ten
	v1.set(map[5][6].getX(), map[5][6].getY());
	v2.set(map[10][1].getX(), map[10][1].getY());
	v1.glDrawTo(v2);
	//Eleven
	v1.set(map[7][6].getX(), map[7][6].getY());
	v2.set(map[11][2].getX(), map[11][2].getY());
	v1.glDrawTo(v2);
	//Twelve
	v1.set(map[9][6].getX(), map[9][6].getY());
	v2.set(map[12][3].getX(), map[12][3].getY());
	v1.glDrawTo(v2);
	//Thirteen
	v1.set(map[12][3].getX(), map[12][3].getY());
	v2.set(map[9][0].getX(), map[9][0].getY());
	v1.glDrawTo(v2);
	//Fourteen
	v1.set(map[11][4].getX(), map[11][4].getY());
	v2.set(map[7][0].getX(), map[7][0].getY());
	v1.glDrawTo(v2);
	//Fifteen
	v1.set(map[11][2].getX(), map[11][2].getY());
	v2.set(map[1][2].getX(), map[1][2].getY());
	v1.glDrawTo(v2);
	//Sixteen
	v1.set(map[10][5].getX(), map[10][5].getY());
	v2.set(map[5][0].getX(), map[5][0].getY());
	v1.glDrawTo(v2);
	//Seventeen
	v1.set(map[9][6].getX(), map[9][6].getY());
	v2.set(map[3][0].getX(), map[3][0].getY());
	v1.glDrawTo(v2);
	//Eighteen
	v1.set(map[7][6].getX(), map[7][6].getY());
	v2.set(map[2][1].getX(), map[2][1].getY());
	v1.glDrawTo(v2);
	//Nineteen
	v1.set(map[5][6].getX(), map[5][6].getY());
	v2.set(map[1][2].getX(), map[1][2].getY());
	v1.glDrawTo(v2);
	//Twenty
	v1.set(map[3][6].getX(), map[3][6].getY());
	v2.set(map[0][3].getX(), map[0][3].getY());
	v1.glDrawTo(v2);
	//Twenty One
	v1.set(map[10][1].getX(), map[10][1].getY());
	v2.set(map[2][1].getX(), map[2][1].getY());
	v1.glDrawTo(v2);
	//Twenty Two
	v1.set(map[9][0].getX(), map[9][0].getY());
	v2.set(map[3][0].getX(), map[3][0].getY());
	v1.glDrawTo(v2);
}

void Map::glDraw()
{
	if(map[3][0].notNull() == false) //It doesn't exist in data somewhere.
	{
		//This is where I'll initialize all the values.
		//This...might be a bigger pain than I thought.
		initCells();
	}

	 //These two v2d's will be the only ones I'll use.
	switch(level)
	{
	case 1:
		glColor3ub(0, 0, 255);
		break;
	case 2:
		glColor3ub(0, 255, 0);
		break;
	case 3:
		glColor3ub(255, 0, 0);
		break;
	case 4:
		glColor3ub(55, 0, 255); //Purple!
		break;
	}
	drawLines();
	
	for(int i = 0; i < 13; i++)
	{
		for(int k = 0; k < 7; k++)
		{
			switch(i)
			{
			case 0:
			case 12:
				if(k == 3)
				{
					map[i][k].glDraw();
				}
				break;
			case 1:
			case 11:
				if(k == 2 || k == 4)
				{
					map[i][k].glDraw();
				}
				break;
			case 2:
			case 4:
			case 6:
			case 8:
			case 10:
				if(k == 1 || k == 3 || k == 5)
				{
					map[i][k].glDraw();
				}
				break;
			case 3:
			case 5:
			case 7:
			case 9:
				if(k == 0 || k == 2 || k == 4 || k == 6)
				{
					map[i][k].glDraw();
				}
				break;
			}
		}
	}
}

int Map::getDots(int x, int y)
{
	return map[x][y].getDots();
}

Cell& Map::getCell(float x, float y)
{
	for(int i = 0; i < 13; i++)
	{
		for(int k = 0; k < 7; k++)
		{
			if(map[i][k].getX() == x && map[i][k].getY() == y)
				return map[i][k];
		}
	}
	return map[0][0];
}

void Map::changeLevel()
{
	level += 1;
	switch(level)
	{
	case 2:
		initLevelTwo();
		break;
	case 3:
		initLevelThree();
		break;
	case 4:
		initLevelFour();
		break;
	}
	//Dammit. Can't even use a static int for the levels...
	for(int i = 0; i < 13; i++)
		for(int k = 0; k < 7; k++)
			map[i][k].changeLevel(level);
	if(level != 4)
	{
		setSurvive();
	}
}

//EVERYTHING BELOW THIS COMMENT IS STUFF YOU ALL SHOULD AVOID. THIS IS WHAT THEY CALL PAIN. 
//Also, I don't mind if anybody wants to finish them up. In fact, I'd probably be grateful for it.

void Map::initLevelTwo()
{
	//Vaganov thought of a much better way to do these, and I personally agree with that. However, as these work ftm, I'll go with these.
	map[3][0].setDots(0);
	map[5][0].setDots(1);								//4 circls
	map[7][0].setDots(0);
	map[9][0].setDots(2);
	//second row
	map[2][1].setDots(4);
	map[4][1].setDots(2);
	map[6][1].setDots(3);								//5circls
	map[8][1].setDots(2);
	map[10][1].setDots(2);

	//third row
	map[1][2].setDots(0); 
	map[3][2].setDots(3); 
	map[5][2].setDots(4); 
	map[7][2].setDots(1);								//6 circls
	map[9][2].setDots(2); 
	map[11][2].setDots(0);  

	//fourth row
	map[0][3].setDots(2);
	map[2][3].setDots(1);
	map[4][3].setDots(3);
	map[6][3].setDots(0);								//7 circls
	map[8][3].setDots(2);
	map[10][3].setDots(4);
	map[12][3].setDots(3);

	//fifth row
	map[1][4].setDots(4); 
	map[3][4].setDots(3); 
	map[5][4].setDots(4); 
	map[7][4].setDots(1);								//6 circls
	map[9][4].setDots(4); 
	map[11][4].setDots(1); 
	//six row
	map[2][5].setDots(0);
	map[4][5].setDots(4);
	map[6][5].setDots(4);								//5 circls
	map[8][5].setDots(2);
	map[10][5].setDots(0);

	// seven row
	map[3][6].setDots(0);
	map[5][6].setDots(4);
	map[7][6].setDots(1);								//4 circls
	map[9][6].setDots(2);

	setSurvive();
}

void Map::initLevelThree()
{
	map[3][0].setDots(3);
	map[5][0].setDots(4);								//4 circls
	map[7][0].setDots(3);
	map[9][0].setDots(1);
	//second row
	map[2][1].setDots(4);
	map[4][1].setDots(1);
	map[6][1].setDots(0);								//5circls
	map[8][1].setDots(3);
	map[10][1].setDots(4);

	//third row
	map[1][2].setDots(3); 
	map[3][2].setDots(3); 
	map[5][2].setDots(3); 
	map[7][2].setDots(2);								//6 circls
	map[9][2].setDots(0); 
	map[11][2].setDots(4);  

	//fourth row
	map[0][3].setDots(2);
	map[2][3].setDots(1);
	map[4][3].setDots(3);
	map[6][3].setDots(0);								//7 circls
	map[8][3].setDots(4);
	map[10][3].setDots(4);
	map[12][3].setDots(1);

	//fifth row
	map[1][4].setDots(4); 
	map[3][4].setDots(0); 
	map[5][4].setDots(3); 
	map[7][4].setDots(3);								//6 circls
	map[9][4].setDots(2); 
	map[11][4].setDots(1); 
	//six row
	map[2][5].setDots(3);
	map[4][5].setDots(2);
	map[6][5].setDots(1);								//5 circls
	map[8][5].setDots(2);
	map[10][5].setDots(2);

	// seven row
	map[3][6].setDots(1);
	map[5][6].setDots(1);
	map[7][6].setDots(2);								//4 circls
	map[9][6].setDots(1);

	setSurvive();
}

void Map::initLevelFour()
{
	map[3][0].setDots(2);
	map[5][0].setDots(1);								//4 circls
	map[7][0].setDots(2);
	map[9][0].setDots(3);
	//second row
	map[2][1].setDots(3);
	map[4][1].setDots(3);
	map[6][1].setDots(4);								//5circls
	map[8][1].setDots(1);
	map[10][1].setDots(3);

	//third row
	map[1][2].setDots(3); 
	map[3][2].setDots(2); 
	map[5][2].setDots(2); 
	map[7][2].setDots(3);								//6 circls
	map[9][2].setDots(2); 
	map[11][2].setDots(1);  

	//fourth row
	map[0][3].setDots(1);
	map[2][3].setDots(4);
	map[4][3].setDots(2);
	map[6][3].setDots(0);								//7 circls
	map[8][3].setDots(2);
	map[10][3].setDots(4);
	map[12][3].setDots(1);

	//fifth row
	map[1][4].setDots(1); 
	map[3][4].setDots(4); 
	map[5][4].setDots(3); 
	map[7][4].setDots(3);								//6 circls
	map[9][4].setDots(4); 
	map[11][4].setDots(3); 
	//six row
	map[2][5].setDots(2);
	map[4][5].setDots(2);
	map[6][5].setDots(2);								//5 circls
	map[8][5].setDots(1);
	map[10][5].setDots(1);

	// seven row
	map[3][6].setDots(3);
	map[5][6].setDots(1);
	map[7][6].setDots(1);								//4 circls
	map[9][6].setDots(2);

	setSurvive();
	map[6][3].setSurvive(true);
}